<html>
 <head>
  <meta charset="utf-8"/>
  <meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport"/>
  <title>
   Spark SQL深度理解篇：模块实现、代码结构及执行流程总览  | 数螺 | NAUT IDEA
  </title>
  <link href="http://cdn.bootcss.com/bootstrap/3.3.6/css/bootstrap-theme.min.css" rel="stylesheet"/>
  <link href="http://cdn.bootcss.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
  <style type="text/css">
   #xmain img {
                  max-width: 100%;
                  display: block;
                  margin-top: 10px;
                  margin-bottom: 10px;
                }

                #xmain p {
                    line-height:150%;
                    font-size: 16px;
                    margin-top: 20px;
                }

                #xmain h2 {
                    font-size: 24px;
                }

                #xmain h3 {
                    font-size: 20px;
                }

                #xmain h4 {
                    font-size: 18px;
                }


                .header {
	           background-color: #0099ff;
	           color: #ffffff;
	           margin-bottom: 20px;
	        }

	        .header p {
                  margin: 0px;
                  padding: 10px 0;
                  display: inline-block;  
                  vertical-align: middle;
                  font-size: 16px;
               }

               .header a {
                 color: white;
               }

              .header img {
                 height: 25px;
              }
  </style>
  <script src="http://cdn.bootcss.com/jquery/3.0.0/jquery.min.js">
  </script>
  <script src="http://nautstatic-10007657.file.myqcloud.com/static/css/readability.min.js" type="text/javascript">
  </script>
  <script type="text/javascript">
   $(document).ready(function() {
                 var loc = document.location;
                 var uri = {
                  spec: "http://dataunion.org/2813.html",
                  host: "http://dataunion.org",
                  prePath: "http://dataunion.org",
                  scheme: "http",
                  pathBase: "http://dataunion.org/"
                 };
    
                 var documentClone = document.cloneNode(true);
                 var article = new Readability(uri, documentClone).parse();
     
                 document.getElementById("xmain").innerHTML = article.content;
                });
  </script>
  <!-- 1466457486: Accept with keywords: (title(0.222222222222):社区,流程,数盟,模块,深度,Spark,总览,代码,结构, topn(0.366666666667):社区,定义,子类,流程,算子,数据类型,数盟,过程,hadoop,计划,基础架构,文章,Spark,数据,节点,结构,体系,语法,规则,spark,优化,抽象类,逻辑,策略,方法,代码,系统,模块,时候,物理).-->
 </head>
 <body onload="">
  <div class="header">
   <div class="container">
    <div class="row">
     <div class="col-xs-6 col-sm-6 text-left">
      <a href="/databee">
       <img src="http://nautidea-10007657.cos.myqcloud.com/logo_white.png"/>
      </a>
      <a href="/databee">
       <p>
        数螺
       </p>
      </a>
     </div>
     <div class="hidden-xs col-sm-6 text-right">
      <p>
       致力于数据科学的推广和知识传播
      </p>
     </div>
    </div>
   </div>
  </div>
  <div class="container text-center">
   <h1>
    Spark SQL深度理解篇：模块实现、代码结构及执行流程总览
   </h1>
  </div>
  <div class="container" id="xmain">
   ﻿﻿
   <title>
    Spark SQL深度理解篇：模块实现、代码结构及执行流程总览 | 数盟社区
   </title>
   <!-- All in One SEO Pack 2.2.7.6.2 by Michael Torbert of Semper Fi Web Design[32,78] -->
   <!-- /all in one seo pack -->
   <!--
<div align="center">
<a href="http://strata.oreilly.com.cn/hadoop-big-data-cn?cmp=mp-data-confreg-home-stcn16_dataunion_pc" target="_blank"><img src="http://dataunion.org/wp-content/uploads/2016/05/stratabj.jpg"/ ></a>
</div>
-->
   <header id="header-web">
    <div class="header-main">
     <hgroup class="logo">
      <h1>
       <a href="http://dataunion.org/" rel="home" title="数盟社区">
        <img src="http://dataunion.org/wp-content/themes/yzipi/images/logo.png"/>
       </a>
      </h1>
     </hgroup>
     <!--logo-->
     <nav class="header-nav">
      <ul class="menu" id="menu-%e4%b8%bb%e8%8f%9c%e5%8d%95">
       <li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-has-children menu-item-71" id="menu-item-71">
        <a href="http://dataunion.org/category/events" title="events">
         活动
        </a>
        <ul class="sub-menu">
         <li class="menu-item menu-item-type-post_type menu-item-object-page menu-item-22457" id="menu-item-22457">
          <a href="http://dataunion.org/2016timeline">
           2016档期
          </a>
         </li>
         <li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-22459" id="menu-item-22459">
          <a href="http://dataunion.org/category/parterc">
           合作会议
          </a>
         </li>
        </ul>
       </li>
       <li class="menu-item menu-item-type-taxonomy menu-item-object-category current-post-ancestor menu-item-has-children menu-item-20869" id="menu-item-20869">
        <a href="http://dataunion.org/category/tech" title="articles">
         文章
        </a>
        <ul class="sub-menu">
         <li class="menu-item menu-item-type-taxonomy menu-item-object-category current-post-ancestor current-menu-parent current-post-parent menu-item-20867" id="menu-item-20867">
          <a href="http://dataunion.org/category/tech/base" title="base">
           基础架构
          </a>
         </li>
         <li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-3302" id="menu-item-3302">
          <a href="http://dataunion.org/category/tech/ai" title="ai">
           人工智能
          </a>
         </li>
         <li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-3303" id="menu-item-3303">
          <a href="http://dataunion.org/category/tech/analysis" title="analysis">
           数据分析
          </a>
         </li>
         <li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-21920" id="menu-item-21920">
          <a href="http://dataunion.org/category/tech/dm">
           数据挖掘
          </a>
         </li>
         <li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-3314" id="menu-item-3314">
          <a href="http://dataunion.org/category/tech/viz" title="viz">
           可视化
          </a>
         </li>
         <li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-3305" id="menu-item-3305">
          <a href="http://dataunion.org/category/tech/devl" title="devl">
           编程语言
          </a>
         </li>
        </ul>
       </li>
       <li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-has-children menu-item-20876" id="menu-item-20876">
        <a href="http://dataunion.org/category/industry">
         行业
        </a>
        <ul class="sub-menu">
         <li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-16328" id="menu-item-16328">
          <a href="http://dataunion.org/category/industry/case" title="case">
           行业应用
          </a>
         </li>
         <li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-2112" id="menu-item-2112">
          <a href="http://dataunion.org/category/industry/demo" title="demo">
           Demo展示
          </a>
         </li>
         <li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-21562" id="menu-item-21562">
          <a href="http://dataunion.org/category/industry/news">
           行业资讯
          </a>
         </li>
        </ul>
       </li>
       <li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-311" id="menu-item-311">
        <a href="http://dataunion.org/category/sources" title="sources">
         资源
        </a>
       </li>
       <li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-20870" id="menu-item-20870">
        <a href="http://dataunion.org/category/books" title="book">
         图书
        </a>
       </li>
       <li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-21363" id="menu-item-21363">
        <a href="http://dataunion.org/category/training">
         课程
        </a>
       </li>
       <li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-has-children menu-item-21853" id="menu-item-21853">
        <a href="http://dataunion.org/category/jobs">
         职位
        </a>
        <ul class="sub-menu">
         <li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-22050" id="menu-item-22050">
          <a href="http://dataunion.org/category/career">
           职业规划
          </a>
         </li>
        </ul>
       </li>
      </ul>
     </nav>
     <!--header-nav-->
    </div>
   </header>
   <!--header-web-->
   <div id="main">
    <div id="soutab">
     <form action="http://dataunion.org/" class="search" method="get">
     </form>
    </div>
    <div id="container">
     <nav id="mbx">
      当前位置：
      <a href="http://dataunion.org">
       首页
      </a>
      &gt;
      <a href="http://dataunion.org/category/tech">
       文章
      </a>
      &gt;
      <a href="http://dataunion.org/category/tech/base">
       基础架构
      </a>
      &gt;  正文
     </nav>
     <!--mbx-->
     <article class="content">
      <header align="centre" class="contenttitle">
       <div class="mscc">
        <h1 class="mscctitle">
         <a href="http://dataunion.org/2813.html">
          Spark SQL深度理解篇：模块实现、代码结构及执行流程总览
         </a>
        </h1>
        <address class="msccaddress ">
         <em>
          3,046 次阅读 -
         </em>
         <a href="http://dataunion.org/category/tech/base" rel="category tag">
          基础架构
         </a>
        </address>
       </div>
      </header>
      <div class="content-text">
       <h4>
        在2014年7月1日的Spark Summit上，Databricks宣布终止对Shark的开发，将重点放到Spark SQL上。Spark SQL将涵盖Shark的所有特性，用户可以从Shark 0.9进行无缝的升级。日前
        <a href="http://blog.csdn.net/pelick" target="_blank">
         张包峰
        </a>
        的博客上分享了Spark SQL各个模块的实现情况、代码结构、执行流程以及对Spark SQL的理解。
       </h4>
       <div>
        <b>
         以下为原文：
        </b>
       </div>
       <h1>
        <b>
         Catalyst
        </b>
       </h1>
       <p>
        Catalyst是与Spark解耦的一个独立库，是一个impl-free的执行计划的生成和优化框架。
       </p>
       <p>
        目前与Spark Core还是耦合的，对此user邮件组里有人对此提出疑问，见mail。
       </p>
       <p>
        以下是Catalyst较早时候的架构图，展示的是代码结构和处理流程。
       </p>
       <p>
        <a href="http://cms.csdnimg.cn/article/201407/15/53c4cfb67bdfb.jpg" target="_blank">
         <img src="http://cms.csdnimg.cn/article/201407/15/53c4cfb67bdfb_middle.jpg?_=45242"/>
        </a>
       </p>
       <p>
        <b>
         Catalyst定位
        </b>
       </p>
       <p>
        其他系统如果想基于Spark做一些类sql、标准sql甚至其他查询语言的查询，需要基于Catalyst提供的解析器、执行计划树结构、逻辑执行计划的处理规则体系等类体系来实现执行计划的解析、生成、优化、映射工作。
       </p>
       <p>
        对应上图中，主要是左侧的TreeNodelib及中间三次转化过程中涉及到的类结构都是Catalyst提供的。至于右侧物理执行计划映射生成过程，物理执行计划基于成本的优化模型，具体物理算子的执行都由系统自己实现。
       </p>
       <p>
        <b>
         Catalyst现状
        </b>
       </p>
       <p>
        在解析器方面提供的是一个简单的scala写的sql parser，支持语义有限，而且应该是标准sql的。
       </p>
       <p>
        在规则方面，提供的优化规则是比较基础的(和Pig/Hive比没有那么丰富)，不过一些优化规则其实是要涉及到具体物理算子的，所以部分规则需要在系统方那自己制定和实现(如spark-sql里的SparkStrategy)。
       </p>
       <p>
        Catalyst也有自己的一套数据类型。
       </p>
       <p>
        下面介绍Catalyst里几套重要的类结构。
       </p>
       <h2>
        <b>
         TreeNode体系
        </b>
       </h2>
       <p>
        TreeNode是Catalyst执行计划表示的数据结构，是一个树结构，具备一些scala collection的操作能力和树遍历能力。这棵树一直在内存里维护，不会dump到磁盘以某种格式的文件存在，且无论在映射逻辑执行计划阶段还是优化逻辑执行计划阶段，树的修改是以替换已有节点的方式进行的。
       </p>
       <p>
        TreeNode，内部带一个children: Seq[BaseType]表示孩子节点，具备foreach、map、collect等针对节点操作的方法，以及transformDown(默认，前序遍历)、transformUp这样的遍历树上节点，对匹配节点实施变化的方法。
       </p>
       <p>
        提供UnaryNode,BinaryNode, LeafNode三种trait，即非叶子节点允许有一个或两个子节点。
       </p>
       <p>
        TreeNode提供的是范型。
       </p>
       <p>
        TreeNode有两个子类继承体系，QueryPlan和Expression。QueryPlan下面是逻辑和物理执行计划两个体系，前者在Catalyst里有详细实现，后者需要在系统自己实现。Expression是表达式体系，后面章节都会展开介绍。
       </p>
       <p>
        <a href="http://cms.csdnimg.cn/article/201407/15/53c4cfef9be92.jpg" target="_blank">
         <img src="http://cms.csdnimg.cn/article/201407/15/53c4cfef9be92_middle.jpg?_=40581"/>
        </a>
       </p>
       <p>
        Tree的transformation实现：
       </p>
       <p>
        传入PartialFunction[TreeType,TreeType]，如果与操作符匹配，则节点会被结果替换掉，否则节点不会变动。整个过程是对children递归执行的。
       </p>
       <h2>
        执行计划表示模型
       </h2>
       <p>
        <b>
         逻辑执行计划
        </b>
       </p>
       <p>
        QueryPlan继承自TreeNode，内部带一个output: Seq[Attribute],具备transformExpressionDown、transformExpressionUp方法。
       </p>
       <p>
        在Catalyst中，QueryPlan的主要子类体系是LogicalPlan，即逻辑执行计划表示。其物理执行计划表示由使用方实现(spark-sql项目中)。
       </p>
       <p>
        LogicalPlan继承自QueryPlan，内部带一个reference:Set[Attribute]，主要方法为resolve(name:String): Option[NamedeExpression]，用于分析生成对应的NamedExpression。
       </p>
       <p>
        LogicalPlan有许多具体子类，也分为UnaryNode, BinaryNode, LeafNode三类，具体在org.apache.spark.sql.catalyst.plans.logical路径下。
       </p>
       <p>
        <a href="http://cms.csdnimg.cn/article/201407/15/53c4d03101f8a.jpg" target="_blank">
         <img src="http://cms.csdnimg.cn/article/201407/15/53c4d03101f8a.jpg"/>
        </a>
       </p>
       <p>
        <strong>
         逻辑执行计划实现
        </strong>
       </p>
       <p>
        LeafNode主要子类是Command体系：
       </p>
       <p>
        <a href="http://cms.csdnimg.cn/article/201407/15/53c4d06bd2874.jpg" target="_blank">
         <img src="http://cms.csdnimg.cn/article/201407/15/53c4d06bd2874.jpg"/>
        </a>
       </p>
       <p>
        各command的语义可以从子类名字看出，代表的是系统可以执行的non-query命令，如DDL。
       </p>
       <p>
        UnaryNode的子类：
       </p>
       <p>
        <a href="http://cms.csdnimg.cn/article/201407/15/53c4d0b468fde.jpg" target="_blank">
         <img src="http://cms.csdnimg.cn/article/201407/15/53c4d0b468fde.jpg"/>
        </a>
       </p>
       <p>
        BinaryNode的子类：
       </p>
       <p>
        <a href="http://cms.csdnimg.cn/article/201407/15/53c4d0d96345f.jpg" target="_blank">
         <img src="http://cms.csdnimg.cn/article/201407/15/53c4d0d96345f.jpg"/>
        </a>
       </p>
       <p>
        <strong>
         物理执行计划
        </strong>
       </p>
       <p>
        另一方面，
        <strong>
         物理执行计划
        </strong>
        节点在具体系统里实现，比如spark-sql工程里的SparkPlan继承体系。
       </p>
       <p>
        <a href="http://cms.csdnimg.cn/article/201407/15/53c4d0fca0424.jpg" target="_blank">
         <img src="http://cms.csdnimg.cn/article/201407/15/53c4d0fca0424.jpg"/>
        </a>
       </p>
       <p>
        <b>
         物理执行计划实现
        </b>
       </p>
       <p>
        每个子类都要实现execute()方法，大致有以下实现子类(不全)。
       </p>
       <p>
        <a href="http://cms.csdnimg.cn/article/201407/15/53c4d158104b6.jpg" target="_blank">
         <img src="http://cms.csdnimg.cn/article/201407/15/53c4d158104b6.jpg"/>
        </a>
       </p>
       <p>
        提到物理执行计划，还要提一下Catalyst提供的分区表示模型。
       </p>
       <p>
        <b>
         执行计划映射
        </b>
       </p>
       <p>
        Catalyst还提供了一个QueryPlanner[Physical &lt;: TreeNode[PhysicalPlan]]抽象类，需要子类制定一批strategies: Seq[Strategy]，其apply方法也是类似根据制定的具体策略来把逻辑执行计划算子映射成物理执行计划算子。由于物理执行计划的节点是在具体系统里实现的，所以QueryPlanner及里面的strategies也需要在具体系统里实现。
       </p>
       <p>
        <a href="http://cms.csdnimg.cn/article/201407/15/53c4d18315fed.jpg" target="_blank">
         <img src="http://cms.csdnimg.cn/article/201407/15/53c4d18315fed.jpg"/>
        </a>
       </p>
       <p>
        在spark-sql项目中，SparkStrategies继承了QueryPlanner[SparkPlan]，内部制定了LeftSemiJoin, HashJoin,PartialAggregation, BroadcastNestedLoopJoin, CartesianProduct等几种策略，每种策略接受的都是一个LogicalPlan，生成的是Seq[SparkPlan]，每个SparkPlan理解为具体RDD的算子操作。
       </p>
       <p>
        比如在BasicOperators这个Strategy里，以match-case匹配的方式处理了很多基本算子（可以一对一直接映射成RDD算子），如下：
       </p>
       <p>
        <a href="http://cms.csdnimg.cn/article/201407/15/53c4d1c123748.jpg" target="_blank">
         <img src="http://cms.csdnimg.cn/article/201407/15/53c4d1c123748_middle.jpg?_=42136"/>
        </a>
       </p>
       <h2>
        Expression体系
       </h2>
       <p>
        Expression，即表达式，指不需要执行引擎计算，而可以直接计算或处理的节点，包括Cast操作，Projection操作，四则运算，逻辑操作符运算等。
       </p>
       <p>
        具体可以参考org.apache.spark.sql.expressionspackage下的类。
       </p>
       <h2>
        Rules体系
       </h2>
       <p>
        凡是需要处理执行计划树(Analyze过程，Optimize过程，SparkStrategy过程)，实施规则匹配和节点处理的，都需要继承RuleExecutor[TreeType]抽象类。
       </p>
       <p>
        RuleExecutor内部提供了一个Seq[Batch]，里面定义的是该RuleExecutor的处理步骤。每个Batch代表着一套规则，配备一个策略，该策略说明了迭代次数(一次还是多次)。
       </p>
       <p>
        <a href="http://cms.csdnimg.cn/article/201407/15/53c4d1f9cd33f.jpg" target="_blank">
         <img src="http://cms.csdnimg.cn/article/201407/15/53c4d1f9cd33f_middle.jpg?_=31630"/>
        </a>
       </p>
       <p>
        Rule[TreeType &lt;: TreeNode[_]]是一个抽象类，子类需要复写apply(plan: TreeType)方法来制定处理逻辑。
       </p>
       <p>
        RuleExecutor的apply(plan: TreeType): TreeType方法会按照batches顺序和batch内的Rules顺序，对传入的plan里的节点迭代处理，处理逻辑为由具体Rule子类实现。
       </p>
       <h1>
        Hive相关
       </h1>
       <h2>
        Hive支持方式
       </h2>
       <p>
        Spark SQL对hive的支持是单独的spark-hive项目，对Hive的支持包括HQL查询、hive metaStore信息、hive SerDes、hive UDFs/UDAFs/ UDTFs，类似Shark。
       </p>
       <p>
        只有在HiveContext下通过hive api获得的数据集，才可以使用hql进行查询，其hql的解析依赖的是org.apache.hadoop.hive.ql.parse.ParseDriver类的parse方法，生成Hive AST。
       </p>
       <p>
        实际上sql和hql，并不是一起支持的。可以理解为hql是独立支持的，能被hql查询的数据集必须读取自hive api。下图中的parquet、json等其他文件支持只发生在sql环境下(SQLContext)。
       </p>
       <p>
        <a href="http://cms.csdnimg.cn/article/201407/15/53c4d22d25eb0.jpg" target="_blank">
         <img src="http://cms.csdnimg.cn/article/201407/15/53c4d22d25eb0.jpg"/>
        </a>
       </p>
       <h2>
        Hive on Spark
       </h2>
       <p>
        Hive官方提出了Hive onSpark的JIRA。Shark结束之后，拆分为两个方向：
       </p>
       <p>
        <a href="http://cms.csdnimg.cn/article/201407/15/53c4d271cb230.jpg" target="_blank">
         <img src="http://cms.csdnimg.cn/article/201407/15/53c4d271cb230.jpg"/>
        </a>
       </p>
       <p>
        从这里看，对Hive的兼容支持将转移到Hive on Spark上，之前Shark的经验将在Hive社区的这个支持上体现。我理解，目前SparkSQL里的那种Hive支持方式，只是为了在Spark环境下集成操纵Hive数据，它的hql执行是调用Hive客户端Driver，跑在hadoop MR上的，本身不是Hive on Spark的实现，只是为了使用RDD间接操作Hive数据集。
       </p>
       <p>
        所以如果想要把现有Hive任务迁移到Spark上，应该使用Shark或者等待Hive on Spark。
       </p>
       <p>
        Spark SQL里的Hive支持不是hive on spark的实现，而更像一个读写Hive数据的客户端。且其hql支持只包含hive数据，与sql环境是互相独立的。
       </p>
       <p>
        以上两节是Spark SQL Hive、Shark、Hive on Spark的区别和理解。
       </p>
       <h1>
        SQL Core
       </h1>
       <p>
        Spark SQL的核心是把已有的RDD，带上Schema信息，然后注册成类似sql里的”Table”，对其进行sql查询。这里面主要分两部分，一是生成SchemaRD，二是执行查询。
       </p>
       <h2>
        生成SchemaRDD
       </h2>
       <p>
        如果是spark-hive项目，那么读取metadata信息作为Schema、读取hdfs上数据的过程交给Hive完成，然后根据这俩部分生成SchemaRDD，在HiveContext下进行hql()查询。
       </p>
       <p>
        对于Spark SQL来说，
       </p>
       <p>
        数据方面，RDD可以来自任何已有的RDD，也可以来自支持的第三方格式，如json file、parquet file。
       </p>
       <p>
        SQLContext下会把带case class的RDD隐式转化为SchemaRDD
       </p>
       <p>
        <a href="http://cms.csdnimg.cn/article/201407/15/53c4d2d28212c.jpg" target="_blank">
         <img src="http://cms.csdnimg.cn/article/201407/15/53c4d2d28212c_middle.jpg?_=2582"/>
        </a>
       </p>
       <p>
        ExsitingRdd单例里会反射出case class的attributes，并把RDD的数据转化成Catalyst的GenericRow，最后返回RDD[Row]，即一个SchemaRDD。这里的具体转化逻辑可以参考ExsitingRdd的productToRowRdd和convertToCatalyst方法。
       </p>
       <p>
        之后可以进行SchemaRDD提供的注册table操作、针对Schema复写的部分RDD转化操作、DSL操作、saveAs操作等等。
       </p>
       <p>
        <b>
         Row和GenericRow是Catalyst里的行表示模型
        </b>
       </p>
       <p>
        Row用Seq[Any]来表示values，GenericRow是Row的子类，用数组表示values。Row支持数据类型包括Int, Long, Double, Float, Boolean, Short, Byte, String。支持按序数(ordinal)读取某一个列的值。读取前需要做isNullAt(i: Int)的判断。
       </p>
       <p>
        各自都有Mutable类，提供setXXX(i: int, value: Any)修改某序数上的值。
       </p>
       <h2>
        层次结构
       </h2>
       <p>
        <a href="http://cms.csdnimg.cn/article/201407/15/53c4d3cc258ff.jpg" target="_blank">
         <img src="http://cms.csdnimg.cn/article/201407/15/53c4d3cc258ff_middle.jpg?_=40944"/>
        </a>
       </p>
       <p>
        下图大致对比了Pig，Spark SQL，Shark在实现层次上的区别，仅做参考。
       </p>
       <p>
        <a href="http://cms.csdnimg.cn/article/201407/15/53c4d4769aaab.jpg" target="_blank">
         <img src="http://cms.csdnimg.cn/article/201407/15/53c4d4769aaab_middle.jpg?_=14654"/>
        </a>
       </p>
       <p>
        <a href="http://cms.csdnimg.cn/article/201407/15/53c4d49a45543.jpg" target="_blank">
         <img src="http://cms.csdnimg.cn/article/201407/15/53c4d49a45543_middle.jpg?_=50918"/>
        </a>
       </p>
       <h2>
        查询流程
       </h2>
       <p>
        SQLContext里对sql的一个解析和执行流程：
       </p>
       <p>
        1.  第一步parseSql(sql: String)，simple sql parser做词法语法解析，生成LogicalPlan。
       </p>
       <p>
        2.  第二步analyzer(logicalPlan)，把做完词法语法解析的执行计划进行初步分析和映射，
       </p>
       <p>
        目前SQLContext内的Analyzer由Catalyst提供，定义如下：
       </p>
       <p>
        new Analyzer(catalog, EmptyFunctionRegistry, caseSensitive =true)
       </p>
       <p>
        catalog为SimpleCatalog，catalog是用来注册table和查询relation的。
       </p>
       <p>
        而这里的FunctionRegistry不支持lookupFunction方法，所以该analyzer不支持Function注册，即UDF。
       </p>
       <p>
        Analyzer内定义了几批规则：
       </p>
       <p>
        <a href="http://cms.csdnimg.cn/article/201407/15/53c4d4d5a403a.jpg" target="_blank">
         <img src="http://cms.csdnimg.cn/article/201407/15/53c4d4d5a403a_middle.jpg?_=44528"/>
        </a>
       </p>
       <p>
        3.  从第二步得到的是初步的logicalPlan，接下来第三步是optimizer(plan)。
       </p>
       <p>
        Optimizer里面也是定义了几批规则，会按序对执行计划进行优化操作。
       </p>
       <p>
        <a href="http://cms.csdnimg.cn/article/201407/15/53c4d53b73731.jpg" target="_blank">
         <img src="http://cms.csdnimg.cn/article/201407/15/53c4d53b73731_middle.jpg?_=15268"/>
        </a>
       </p>
       <p>
        4.  优化后的执行计划，还要丢给SparkPlanner处理，里面定义了一些策略，目的是根据逻辑执行计划树生成最后可以执行的物理执行计划树，即得到SparkPlan。
       </p>
       <p>
        <a href="http://cms.csdnimg.cn/article/201407/15/53c4d5696a714.jpg" target="_blank">
         <img src="http://cms.csdnimg.cn/article/201407/15/53c4d5696a714_middle.jpg?_=61134"/>
        </a>
       </p>
       <p>
        5.  在最终真正执行物理执行计划前，最后还要进行两次规则，SQLContext里定义这个过程叫prepareForExecution，这个步骤是额外增加的，直接new RuleExecutor[SparkPlan]进行的。
       </p>
       <p>
        <a href="http://cms.csdnimg.cn/article/201407/15/53c4d593803a5.jpg" target="_blank">
         <img src="http://cms.csdnimg.cn/article/201407/15/53c4d593803a5_middle.jpg?_=36976"/>
        </a>
       </p>
       <p>
        6.  最后调用SparkPlan的execute()执行计算。这个execute()在每种SparkPlan的实现里定义，一般都会递归调用children的execute()方法，所以会触发整棵Tree的计算。
       </p>
       <h2>
        其他特性
       </h2>
       <p>
        <b>
         内存列存储
        </b>
       </p>
       <p>
        SQLContext下cache/uncache table的时候会调用列存储模块。
       </p>
       <p>
        该模块借鉴自Shark，目的是当把表数据cache在内存的时候做行转列操作，以便压缩。
       </p>
       <p>
        <b>
         实现类
        </b>
       </p>
       <p>
        InMemoryColumnarTableScan类是SparkPlan LeafNode的实现，即是一个物理执行计划。传入一个SparkPlan(确认了的物理执行计)和一个属性序列，内部包含一个行转列、触发计算并cache的过程(且是lazy的)。
       </p>
       <p>
        ColumnBuilder针对不同的数据类型(boolean, byte, double, float, int, long, short, string)由不同的子类把数据写到ByteBuffer里，即包装Row的每个field，生成Columns。与其对应的ColumnAccessor是访问column，将其转回Row。
       </p>
       <p>
        CompressibleColumnBuilder和CompressibleColumnAccessor是带压缩的行列转换builder，其ByteBuffer内部存储结构如下
       </p>
       <p>
        <a href="http://cms.csdnimg.cn/article/201407/15/53c4d5e79eac7.jpg" target="_blank">
         <img src="http://cms.csdnimg.cn/article/201407/15/53c4d5e79eac7_middle.jpg?_=56039"/>
        </a>
       </p>
       <p>
        CompressionScheme子类是不同的压缩实现
       </p>
       <p>
        <a href="http://cms.csdnimg.cn/article/201407/15/53c4d6166ad50.jpg" target="_blank">
         <img src="http://cms.csdnimg.cn/article/201407/15/53c4d6166ad50_middle.jpg?_=37117"/>
        </a>
       </p>
       <p>
        都是scala实现的，未借助第三方库。不同的实现，指定了支持的column data类型。在build()的时候，会比较每种压缩，选择压缩率最小的（若仍大于0.8就不压缩了）。
       </p>
       <p>
        这里的估算逻辑，来自子类实现的gatherCompressibilityStats方法。
       </p>
       <p>
        <b>
         Cache逻辑
        </b>
       </p>
       <p>
        cache之前，需要先把本次cache的table的物理执行计划生成出来。
       </p>
       <p>
        在cache这个过程里，InMemoryColumnarTableScan并没有触发执行，但是生成了以InMemoryColumnarTableScan为物理执行计划的SparkLogicalPlan，并存成table的plan。
       </p>
       <p>
        其实在cache的时候，首先去catalog里寻找这个table的信息和table的执行计划，然后会进行执行（执行到物理执行计划生成），然后把这个table再放回catalog里维护起来，这个时候的执行计划已经是最终要执行的物理执行计划了。但是此时Columner模块相关的转换等操作都是没有触发的。
       </p>
       <p>
        真正的触发还是在execute()的时候，同其他SparkPlan的execute()方法触发场景是一样的。
       </p>
       <p>
        <b>
         Uncache逻辑
        </b>
       </p>
       <p>
        UncacheTable的时候，除了删除catalog里的table信息之外，还调用了InMemoryColumnarTableScan的cacheColumnBuffers方法，得到RDD集合，并进行了unpersist()操作。cacheColumnBuffers主要做了把RDD每个partition里的ROW的每个Field存到了ColumnBuilder内。
       </p>
       <p>
        <b>
         UDF（暂不支持）
        </b>
       </p>
       <p>
        如前面对SQLContext里Analyzer的分析，其FunctionRegistry没有实现lookupFunction。
       </p>
       <p>
        在spark-hive项目里，HiveContext里是实现了FunctionRegistry这个trait的，其实现为HiveFunctionRegistry，实现逻辑见org.apache.spark.sql.hive.hiveUdfs
       </p>
       <p>
        <b>
         Parquet支持
        </b>
       </p>
       <p>
        待整理
       </p>
       <p>
        <a href="http://parquet.io/">
         http://parquet.io/
        </a>
       </p>
       <p>
        Specific Docs and Codes:
       </p>
       <p>
        <a href="https://github.com/apache/incubator-parquet-format">
         https://github.com/apache/incubator-parquet-format
        </a>
       </p>
       <p>
        <a href="https://github.com/apache/incubator-parquet-mr">
         https://github.com/apache/incubator-parquet-mr
        </a>
       </p>
       <p>
        <a href="http://www.slideshare.net/julienledem/parquet-hadoop-summit-2013">
         http://www.slideshare.net/julienledem/parquet-hadoop-summit-2013
        </a>
       </p>
       <p>
        <b>
         JSON支持
        </b>
       </p>
       <p>
        SQLContext下，增加了jsonFile的读取方法，而且目前看，代码里实现的是hadoop textfile的读取，也就是这份json文件应该是在HDFS上的。具体这份json文件的载入，InputFormat是TextInputFormat，key class是LongWritable，value class是Text，最后得到的是value部分的那段String内容，即RDD[String]。
       </p>
       <p>
        除了jsonFile，还支持jsonRDD，例子：
       </p>
       <p>
        <a href="http://spark.apache.org/docs/latest/sql-programming-guide.html#json-datasets">
         http://spark.apache.org/docs/latest/sql-programming-guide.html#json-datasets
        </a>
       </p>
       <p>
        读取json文件之后，转换成SchemaRDD。JsonRDD.inferSchema(RDD[String])里有详细的解析json和映射出schema的过程，最后得到该json的LogicalPlan。
       </p>
       <p>
        Json的解析使用的是FasterXML/jackson-databind库，GitHub地址，wiki
       </p>
       <p>
        把数据映射成Map[String, Any]
       </p>
       <p>
        Json的支持丰富了Spark SQL数据接入场景。
       </p>
       <p>
        <b>
         JDBC支持
        </b>
       </p>
       <p>
        Jdbc support branchis under going
       </p>
       <p>
        <b>
         SQL92
        </b>
       </p>
       <p>
        Spark SQL目前的SQL语法支持情况见SqlParser类。目标是支持SQL92？？
       </p>
       <p>
        1. 基本应用上，sql server 和oracle都遵循sql 92语法标准。
       </p>
       <p>
        2. 实际应用中大家都会超出以上标准，使用各家数据库厂商都提供的丰富的自定义标准函数库和语法。
       </p>
       <p>
        3. 微软sql server的sql 扩展叫T-SQL(Transcate SQL).
       </p>
       <p>
        4. Oracle 的sql 扩展叫PL-SQL.
       </p>
       <h1>
        存在问题
       </h1>
       <p>
        大家可以跟进社区邮件列表，后续待整理。
       </p>
       <p>
        <a href="http://apache-spark-developers-list.1001551.n3.nabble.com/sparkSQL-thread-safe-td7263.html">
         http://apache-spark-developers-list.1001551.n3.nabble.com/sparkSQL-thread-safe-td7263.html
        </a>
       </p>
       <p>
        <a href="http://apache-spark-user-list.1001560.n3.nabble.com/Supported-SQL-syntax-in-Spark-SQL-td9538.html">
         http://apache-spark-user-list.1001560.n3.nabble.com/Supported-SQL-syntax-in-Spark-SQL-td9538.html
        </a>
       </p>
       <p>
        <b>
         总结
        </b>
       </p>
       <p>
        以上整理了对Spark SQL各个模块的实现情况，代码结构，执行流程以及自己对Spark SQL的理解。
       </p>
       <p>
        原文链接：
        <a href="http://blog.csdn.net/pelick/article/details/37809681">
         整理对Spark SQL的理解
        </a>
       </p>
       <p>
       </p>
      </div>
      <div>
       <strong>
        注：转载文章均来自于公开网络，仅供学习使用，不会用于任何商业用途，如果侵犯到原作者的权益，请您与我们联系删除或者授权事宜，联系邮箱：contact@dataunion.org。转载数盟网站文章请注明原文章作者，否则产生的任何版权纠纷与数盟无关。
       </strong>
      </div>
      <!--content_text-->
      <div class="fenxian">
       <!-- JiaThis Button BEGIN -->
       <div class="jiathis_style_32x32">
        <p class="jiathis_button_weixin">
        </p>
        <p class="jiathis_button_tsina">
        </p>
        <p class="jiathis_button_qzone">
        </p>
        <p class="jiathis_button_cqq">
        </p>
        <p class="jiathis_button_tumblr">
        </p>
        <a class="jiathis jiathis_txt jtico jtico_jiathis" href="http://www.jiathis.com/share" target="_blank">
        </a>
        <p class="jiathis_counter_style">
        </p>
       </div>
       <!-- JiaThis Button END -->
      </div>
     </article>
     <!--content-->
     <!--相关文章-->
     <div class="xianguan">
      <div class="xianguantitle">
       相关文章！
      </div>
      <ul class="pic">
       <li>
        <a href="http://dataunion.org/13867.html">
         <img src="http://dataunion.org/wp-content/uploads/2015/04/20120310153424_rFtVe.thumb_副本-300x191.jpg"/>
        </a>
        <a class="link" href="http://dataunion.org/13867.html" rel="bookmark" title="平易近人、兼容并蓄——Spark SQL 1.3.0概览">
         平易近人、兼容并蓄——Spark SQL 1.3.0概览
        </a>
       </li>
       <li>
        <a href="http://dataunion.org/11019.html">
         <img src="http://dataunion.org/wp-content/uploads/2015/02/201407171112-300x171.png"/>
        </a>
        <a class="link" href="http://dataunion.org/11019.html" rel="bookmark" title="Spark SQL深度理解">
         Spark SQL深度理解
        </a>
       </li>
       <li>
        <a href="http://dataunion.org/11015.html">
         <img src="http://dataunion.org/wp-content/uploads/2015/02/t0106f0f4d3f42f5e17-300x190.jpg"/>
        </a>
        <a class="link" href="http://dataunion.org/11015.html" rel="bookmark" title="Spark SQL 数据源 API：Spark平台的统一数据接入">
         Spark SQL 数据源 API：Spark平台的统一数据接入
        </a>
       </li>
       <li>
        <a href="http://dataunion.org/24670.html">
         <img src="http://dataunion.org/wp-content/uploads/2016/03/20141222134630106-300x164.png"/>
        </a>
        <a class="link" href="http://dataunion.org/24670.html" rel="bookmark" title="Apache Spark 不过时的六大理由">
         Apache Spark 不过时的六大理由
        </a>
       </li>
      </ul>
     </div>
     <!--相关文章-->
     <div class="comment" id="comments">
      <!-- You can start editing here. -->
      <!-- If comments are open, but there are no comments. -->
      <div class="title">
       期待你一针见血的评论，Come on！
      </div>
      <div id="respond">
       <p>
        不用想啦，马上
        <a href="http://dataunion.org/wp-login.php?redirect_to=http%3A%2F%2Fdataunion.org%2F2813.html">
         "登录"
        </a>
        发表自已的想法.
       </p>
      </div>
     </div>
     <!-- .nav-single -->
    </div>
    <!--Container End-->
    <aside id="sitebar">
     <div class="sitebar_list2">
      <div class="wptag">
       <span class="tagtitle">
        热门标签+
       </span>
       <div class="tagg">
        <ul class="menu" id="menu-%e5%8f%8b%e6%83%85%e9%93%be%e6%8e%a5">
         <li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-1605" id="menu-item-1605">
          <a href="http://taidizh.com/">
           泰迪智慧
          </a>
         </li>
         <li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-20884" id="menu-item-20884">
          <a href="http://www.transwarp.cn/">
           星环科技
          </a>
         </li>
         <li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-3538" id="menu-item-3538">
          <a href="http://datall.org/">
           珈和遥感
          </a>
         </li>
         <li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-20888" id="menu-item-20888">
          <a href="http://www.chinahadoop.cn/">
           小象学院
          </a>
         </li>
        </ul>
       </div>
      </div>
     </div>
     <div class="sitebar_list">
      <div class="textwidget">
       <div align="center">
        <a href="http://study.163.com/course/courseMain.htm?courseId=991022" target="_blank">
         <img src="http://dataunion.org/wp-content/uploads/2016/03/dv.jpg"/>
        </a>
       </div>
      </div>
     </div>
     <div class="sitebar_list">
      <h4 class="sitebar_title">
       文章分类
      </h4>
      <div class="tagcloud">
       <a class="tag-link-44" href="http://dataunion.org/category/industry/demo" style="font-size: 10.204724409449pt;" title="4个话题">
        Demo展示
       </a>
       <a class="tag-link-31" href="http://dataunion.org/category/experts" style="font-size: 15.826771653543pt;" title="52个话题">
        专家团队
       </a>
       <a class="tag-link-870" href="http://dataunion.org/category/tech/ai" style="font-size: 19.795275590551pt;" title="273个话题">
        人工智能
       </a>
       <a class="tag-link-488" href="http://dataunion.org/category/%e5%8a%a0%e5%85%a5%e6%95%b0%e7%9b%9f" style="font-size: 8pt;" title="1个话题">
        加入数盟
       </a>
       <a class="tag-link-869" href="http://dataunion.org/category/tech/viz" style="font-size: 17.204724409449pt;" title="93个话题">
        可视化
       </a>
       <a class="tag-link-30" href="http://dataunion.org/category/partners" style="font-size: 10.645669291339pt;" title="5个话题">
        合作伙伴
       </a>
       <a class="tag-link-889" href="http://dataunion.org/category/parterc" style="font-size: 11.582677165354pt;" title="8个话题">
        合作会议
       </a>
       <a class="tag-link-104" href="http://dataunion.org/category/books" style="font-size: 12.96062992126pt;" title="15个话题">
        图书
       </a>
       <a class="tag-link-220" href="http://dataunion.org/category/tech/base" style="font-size: 19.850393700787pt;" title="281个话题">
        基础架构
       </a>
       <a class="tag-link-219" href="http://dataunion.org/category/tech/analysis" style="font-size: 19.409448818898pt;" title="232个话题">
        数据分析
       </a>
       <a class="tag-link-887" href="http://dataunion.org/category/tech/dm" style="font-size: 13.291338582677pt;" title="17个话题">
        数据挖掘
       </a>
       <a class="tag-link-34" href="http://dataunion.org/category/tech" style="font-size: 20.732283464567pt;" title="404个话题">
        文章
       </a>
       <a class="tag-link-1" href="http://dataunion.org/category/uncategorized" style="font-size: 22pt;" title="693个话题">
        未分类
       </a>
       <a class="tag-link-4" href="http://dataunion.org/category/events" style="font-size: 14.503937007874pt;" title="29个话题">
        活动
       </a>
       <a class="tag-link-890" href="http://dataunion.org/category/tech/%e6%b7%b1%e5%ba%a6%e5%ad%a6%e4%b9%a0" style="font-size: 10.204724409449pt;" title="4个话题">
        深度学习
       </a>
       <a class="tag-link-221" href="http://dataunion.org/category/tech/devl" style="font-size: 18.968503937008pt;" title="193个话题">
        编程语言
       </a>
       <a class="tag-link-888" href="http://dataunion.org/category/career" style="font-size: 15.661417322835pt;" title="48个话题">
        职业规划
       </a>
       <a class="tag-link-5" href="http://dataunion.org/category/jobs" style="font-size: 14.11811023622pt;" title="25个话题">
        职位
       </a>
       <a class="tag-link-871" href="http://dataunion.org/category/industry" style="font-size: 15.716535433071pt;" title="49个话题">
        行业
       </a>
       <a class="tag-link-613" href="http://dataunion.org/category/industry/case" style="font-size: 16.984251968504pt;" title="84个话题">
        行业应用
       </a>
       <a class="tag-link-885" href="http://dataunion.org/category/industry/news" style="font-size: 17.425196850394pt;" title="102个话题">
        行业资讯
       </a>
       <a class="tag-link-10" href="http://dataunion.org/category/training" style="font-size: 14.228346456693pt;" title="26个话题">
        课程
       </a>
       <a class="tag-link-16" href="http://dataunion.org/category/sources" style="font-size: 15.661417322835pt;" title="48个话题">
        资源
       </a>
      </div>
     </div>
     <div class="sitebar_list">
      <h4 class="sitebar_title">
       功能
      </h4>
      <ul>
       <li>
        <a href="http://dataunion.org/wp-login.php?action=register">
         注册
        </a>
       </li>
       <li>
        <a href="http://dataunion.org/wp-login.php">
         登录
        </a>
       </li>
       <li>
        <a href="http://dataunion.org/feed">
         文章
         <abbr title="Really Simple Syndication">
          RSS
         </abbr>
        </a>
       </li>
       <li>
        <a href="http://dataunion.org/comments/feed">
         评论
         <abbr title="Really Simple Syndication">
          RSS
         </abbr>
        </a>
       </li>
       <li>
        <a href="https://cn.wordpress.org/" title="基于WordPress，一个优美、先进的个人信息发布平台。">
         WordPress.org
        </a>
       </li>
      </ul>
     </div>
    </aside>
    <div class="clear">
    </div>
   </div>
   <!--main-->
   ﻿
   <footer id="dibu">
    <div class="about">
     <div class="right">
      <ul class="menu" id="menu-%e5%ba%95%e9%83%a8%e8%8f%9c%e5%8d%95">
       <li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-18024" id="menu-item-18024">
        <a href="http://dataunion.org/category/partners">
         合作伙伴
        </a>
       </li>
       <li class="menu-item menu-item-type-post_type menu-item-object-page menu-item-20881" id="menu-item-20881">
        <a href="http://dataunion.org/contribute">
         文章投稿
        </a>
       </li>
       <li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-20872" id="menu-item-20872">
        <a href="http://dataunion.org/category/%e5%8a%a0%e5%85%a5%e6%95%b0%e7%9b%9f">
         加入数盟
        </a>
       </li>
       <li class="menu-item menu-item-type-post_type menu-item-object-page menu-item-22441" id="menu-item-22441">
        <a href="http://dataunion.org/f-links">
         友情链接
        </a>
       </li>
       <li class="menu-item menu-item-type-post_type menu-item-object-page menu-item-20874" id="menu-item-20874">
        <a href="http://dataunion.org/aboutus">
         关于数盟
        </a>
       </li>
      </ul>
      <p class="banquan">
       数盟社区        ，
        做最棒的数据科学社区
      </p>
     </div>
     <div class="left">
      <ul class="bottomlist">
       <li>
        <a href="http://weibo.com/DataScientistUnion  " target="_blank" 　title="">
         <img src="http://dataunion.org/wp-content/themes/yzipi/images/weibo.png"/>
        </a>
       </li>
       <li>
        <a class="cd-popup-trigger" href="http://dataunion.org/2813.html#0">
         <img src="http://dataunion.org/wp-content/themes/yzipi/images/weixin.png"/>
        </a>
       </li>
      </ul>
      <div class="cd-popup">
       <div class="cd-popup-container">
        <h1>
         扫描二维码,加微信公众号
        </h1>
        <img src="http://dataunion.org/wp-content/themes/yzipi/images/2014-12-06-1515289049.png"/>
        <a class="cd-popup-close" href="http://dataunion.org/2813.html">
        </a>
       </div>
       <!-- cd-popup-container -->
      </div>
      <!-- cd-popup -->
     </div>
    </div>
    <!--about-->
    <div class="bottom">
     <a href="http://dataunion.org/">
      数盟社区
     </a>
     <a href="http://www.miitbeian.gov.cn/" rel="external nofollow" target="_blank">
      京ICP备14026740号
     </a>
     联系我们：
     <a href="mailto:contact@dataunion.org" target="_blank">
      contact@dataunion.org
     </a>
     <div class="tongji">
     </div>
     <!--bottom-->
     <div class="scroll" id="scroll" style="display:none;">
      ︿
     </div>
    </div>
   </footer>
   <!--dibu-->
  </div>
 </body>
</html>